package bb.lanxing.net.okhttp;

import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HttpsURLConnection;

import bb.lanxing.net.client.TokenHeaderInterceptor;
import bb.lanxing.net.core.ApiClient;
import bb.lanxing.net.core.ApiClientConfig;
import bb.lanxing.network.CookieJarImpl;
import okhttp3.Cache;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.internal.tls.OkHostnameVerifier;
import okhttp3.logging.HttpLoggingInterceptor;

public abstract class AbstractOkHttpApiClient<RESPONSE> implements ApiClient<Request, RESPONSE> {
    protected OkHttpClient client;
    protected ApiClientConfig config;

    public AbstractOkHttpApiClient(ApiClientConfig clientConfig) {
        this.config = clientConfig;
    }

    private void buildClientIfNeed() {
        if (this.client != null) {
            return;
        }
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        if (this.config.cacheDir() != null) {
            builder.cache(new Cache(new File(this.config.cacheDir()), this.config.cacheSize()));
        }
        if (this.config.debuggable()) {
//            HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT);
//            httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//            builder.addNetworkInterceptor(httpLoggingInterceptor);
        }
        builder.addNetworkInterceptor(new TokenHeaderInterceptor());
        if (!this.config.getInterceptors().isEmpty()) {
            Iterator<Interceptor> it2 = this.config.getInterceptors().iterator();
            while (it2.hasNext()) {
                builder.addInterceptor(it2.next());
            }
        }
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(message -> {
            //打印retrofit日志
            Log.i("RetrofitLog", "retrofitBack = " + message);
        });
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        builder.addInterceptor(loggingInterceptor);
        HttpsURLConnection.setDefaultHostnameVerifier(OkHostnameVerifier.INSTANCE);
        builder.readTimeout(this.config.readTimeout(), TimeUnit.MILLISECONDS);
        builder.connectTimeout(this.config.connectTimeout(), TimeUnit.MILLISECONDS);
        builder.cookieJar(new CookieJarImpl());
        this.client = builder.build();
    }

    private Request beforeExecute(Request request) {
        buildClientIfNeed();
        Map<String, String> headers = this.config.headers();
        if (headers == null || headers.isEmpty()) {
            return request;
        }
        Headers.Builder newBuilder = request.headers().newBuilder();
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            newBuilder.add(entry.getKey(), entry.getValue());
        }
        return request.newBuilder().headers(newBuilder.build()).build();
    }

    @Override
    public OkHttpClient getOKHttpClient() {
        buildClientIfNeed();
        return this.client;
    }

    public Response doExecute(Request request) throws IOException {
        return this.client.newCall(beforeExecute(request)).execute();
    }
}
